package com.essearch.utils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
public class GenEntity {

    // 指定实体生成所在包的路径
    private String packageOutPath = "com.essearch.entity";
    // 作者名字
    private String authorName = "";
    // 数据库表名
//    private String tablename = "item_01";
    // 列名数组
    private String[] colnames;
    // 列名类型数组
    private String[] colTypes;
    // 列名大小数组
    private int[] colSizes;
    // 是否需要导入包java.util.*
    private boolean f_util = false;
    // 是否需要导入包java.sql.*
    private boolean f_sql = false;

    // 数据库连接
    private static final String URL = "jdbc:mysql://192.168.0.211:3306/st20201010?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8";
    private static final String NAME = "root";
    private static final String PASS = "KJpt123456!@#db";
    private static final String DRIVER = "com.mysql.jdbc.Driver";

    /*
     * 构造函数
     */
    public GenEntity(String tablename) {
        // 创建连接
        Connection con = null;
        // 查要生成实体类的表
        String sql = "select * from " + tablename;
        Statement pStemt = null;
        try {
            try {
                Class.forName(DRIVER);
            } catch (ClassNotFoundException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            con = DriverManager.getConnection(URL, NAME, PASS);
            pStemt = (Statement) con.createStatement();
            ResultSet rs = pStemt.executeQuery(sql);
            ResultSetMetaData rsmd = rs.getMetaData();
            int size = rsmd.getColumnCount(); // 统计列
            colnames = new String[size];
            colTypes = new String[size];
            colSizes = new int[size];
            for (int i = 0; i < size; i++) {
                colnames[i] = rsmd.getColumnName(i + 1);
                colTypes[i] = rsmd.getColumnTypeName(i + 1);

                if (colTypes[i].equalsIgnoreCase("date")
                        || colTypes[i].equalsIgnoreCase("timestamp")) {
                    f_util = true;
                }
                if (colTypes[i].equalsIgnoreCase("blob")
                        || colTypes[i].equalsIgnoreCase("char")) {
                    f_sql = true;
                }
                colSizes[i] = rsmd.getColumnDisplaySize(i + 1);
            }

            String content = parse(tablename, colnames, colTypes, colSizes);

            try {
                File directory = new File("");
                String path = this.getClass().getResource("").getPath();

                System.out.println(path);
                System.out.println("src/main/java"
                        + path.substring(path.lastIndexOf("/com/",
                        path.length())));
                // String outputPath = directory.getAbsolutePath()+
                // "/src/"+path.substring(path.lastIndexOf("/com/",
                // path.length()), path.length()) + initcap(tablename) +
                // ".java";
                String outputPath = directory.getAbsolutePath() + "/src/main/java/"
                        + this.packageOutPath.replace(".", "/") + "/"
                        + initcaps(tablename) + ".java";
                FileWriter fw = new FileWriter(outputPath);
                PrintWriter pw = new PrintWriter(fw);
                pw.println(content);
                pw.flush();
                pw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 功能：生成实体类主体代码
     *
     * @param colnames
     * @param colTypes
     * @param colSizes
     * @return
     */
    private String parse(String tablename, String[] colnames, String[] colTypes, int[] colSizes) {
        StringBuffer sb = new StringBuffer();

        sb.append("package " + this.packageOutPath + ";\r\n");
        sb.append("\r\n");
        sb.append("import com.essearch.common.TableConst;\r\n");
        sb.append("import lombok.Getter;\r\n");
        sb.append("import lombok.Setter;\r\n");
        sb.append("import lombok.ToString;\r\n");
        sb.append("import org.springframework.data.elasticsearch.annotations.Document;\r\n");
        sb.append("import org.springframework.data.elasticsearch.annotations.Field;\r\n");
        sb.append("import org.springframework.data.elasticsearch.annotations.FieldType;\r\n");
        sb.append("import java.io.Serializable;\r\n");
        // 判断是否导入工具包
        if (f_util) {
            sb.append("import java.util.Date;\r\n");
        }
        if (f_sql) {
            sb.append("import java.sql.*;\r\n");
        }
        // 注释部分
        sb.append("/**\r\n");
        sb.append("* " + tablename + " 实体类\r\n");
        sb.append("* " + new Date() + " " + this.authorName + "\r\n");
        sb.append("*/ \r\n");
        // 注解部分
        sb.append("\r\n@Getter\r\n");
        sb.append("@Setter\r\n");
        sb.append("@ToString\r\n");
        sb.append("@Document(indexName = TableConst.INDEX_PRE + \"" + tablename + "\", type = \"" + tablename + "\")\r\n");
        // 实体部分
        sb.append("public class " + initcaps(tablename) + " implements Serializable {\r\n");
        processAllAttrs(sb);// 属性
//        processAllMethod(sb);// get set方法
        sb.append("}\r\n");

        return sb.toString();
    }

    /**
     * 功能：生成所有属性
     *
     * @param sb
     */
    private void processAllAttrs(StringBuffer sb) {

        //@Field(type = FieldType.Keyword)
        //	private String id;
        sb.append("\t@Field(type = FieldType.Keyword)\r\n");
        sb.append("\tprivate String id;\r\n");
        for (int i = 0; i < colnames.length; i++) {
            String type = sqlType2JavaType(colTypes[i]);
            String colname = colnames[i];
            if ("String".equals(type)){
                sb.append("\t@Field(type = FieldType.Text, analyzer = \"ik_smart\", searchAnalyzer = \"ik_smart\")\r\n");
            } else if("Long".equals(type)) {
                sb.append("\t@Field(type = FieldType.Long)\r\n");
            } else {
                sb.append("\t@Field(type = FieldType.Integer)\r\n");
            }

            sb.append("\tprivate " + type + " " + columToJava(colname + ";\r\n"));
        }

    }

    /**
     * 数据字段变成Java属性
     *
     * @param string
     * @return
     */
    public static String columToJava(String string) {
        String string2 = string.toLowerCase();
        StringBuilder builder = new StringBuilder(string2);

        for (int i = 0; i < builder.length(); i++) {
            if (builder.charAt(i) == '_') {
                // 第一次出现该符号的位置
                char c = builder.charAt(i + 1);
                c = (char) (c - 32);
                StringBuilder replace1 = builder.replace(i + 1, i + 2, c + "");
                builder = replace1.replace(i, i + 1, "");

                // 最后一次出现该符号的位置
                int of = builder.lastIndexOf("_", string2.length());
                if (of != -1) {
                    char c1 = builder.charAt(of + 1);
                    c1 = (char) (c1 - 32);
                    StringBuilder replace2 = builder.replace(of + 1, of + 2, c1 + "");
                    builder = replace2.replace(of, of + 1, "");
                }

            }
        }
        return builder.toString();
    }

    /**
     * 功能：生成所有方法
     *
     * @param sb
     */
    private void processAllMethod(StringBuffer sb) {

        for (int i = 0; i < colnames.length; i++) {
            sb.append("\tpublic void set" + initcaps(columToJava(colnames[i]))
                    + "(" + sqlType2JavaType(colTypes[i]) + " "
                    + columToJava(colnames[i]) + "){\r\n");
            sb.append("\t\tthis." + columToJava(colnames[i]) + "="
                    + columToJava(colnames[i]) + ";\r\n");
            sb.append("\t}\r\n");
            sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get"
                    + initcaps(columToJava(colnames[i])) + "(){\r\n");
            sb.append("\t\treturn " + columToJava(colnames[i]) + ";\r\n");
            sb.append("\t}\r\n");
        }

    }

    /**
     * 功能：将输入字符串的首字母改成大写
     *
     * @return
     */
    private String initcap(String string2) {
        String str = columToJava(string2);
        char[] ch = str.toCharArray();
        if (!string2.contains("_")) {
            ch[0] = (char) (ch[0] - 32);
        } else {
            for (int j = 0; j < 3; j++) {
                ch[j] = (char) (ch[j] - 32);
            }
        }
        return new String(ch);
    }

    public static String initcaps(String str) {
        char[] ch = str.toCharArray();
        if (ch[0] >= 'a' && ch[0] <= 'z') {
            ch[0] = (char) (ch[0] - 32);
        }

        return new String(ch);
    }

    /**
     * 功能：获得列的数据类型
     *
     * @param sqlType
     * @return
     */
    private String sqlType2JavaType(String sqlType) {

        if (sqlType.equalsIgnoreCase("binary_double") || sqlType.equalsIgnoreCase("double")) {
            return "Double";
        } else if (sqlType.equalsIgnoreCase("binary_float") || sqlType.equalsIgnoreCase("float")) {
            return "Float";
        } else if (sqlType.equalsIgnoreCase("blob")) {
            return "Byte[]";
        } else if (sqlType.equalsIgnoreCase("char")
                || sqlType.equalsIgnoreCase("text")
                || sqlType.equalsIgnoreCase("nvarchar2")
                || sqlType.equalsIgnoreCase("varchar2")) {
            return "String";
        } else if (sqlType.equalsIgnoreCase("date")
                || sqlType.equalsIgnoreCase("timestamp")
                || sqlType.equalsIgnoreCase("timestamp with local time zone")
                || sqlType.equalsIgnoreCase("timestamp with time zone")) {
            return "Date";
        } else if (sqlType.equalsIgnoreCase("number") || sqlType.equalsIgnoreCase("bigint")) {
            return "Long";
        } else if (sqlType.equalsIgnoreCase("smallint") || sqlType.equalsIgnoreCase("int")) {
            return "Integer";
        }

        return "String";
    }

    /**
     * 出口 TODO
     *
     * @param args
     */
    public static void main(String[] args) {
//        String[] tablenames = {"item_01", "item_01_ext", "item_01_list", "item_01_list2", "item_01_person", "item_02", "item_02_ext", "item_03", "item_03_20181222", "item_03_ext", "item_03_ext_20181222", "item_04", "item_04_ext", "item_05", "item_05_20181222", "item_05_ext", "item_06", "item_06_ext", "item_06_jfbz", "item_06_sbyq", "item_06_yjkfhd", "item_06_zonghe", "item_06_zycp", "item_06_zykt", "item_07", "item_07_ext", "item_08", "item_08_ext", "item_09", "item_09_cwzk", "item_09_fee", "item_09_ryjg", "item_09_yjfx", "item_10", "item_10_ext", "item_10_kjjlxm", "item_10_lw", "item_10_ptjd", "item_10_sqxzl", "item_10_zykjxm", "item_11", "item_11_ext", "item_11_hzjbqk", "item_12", "item_12_ext", "item_13", "item_14", "item_14_ext", "item_15", "item_15_ext", "item_16",
//                "item_main", "item_person", "item_person_base", "item_person_edu", "item_person_ext", "item_person_work", "item_unit", "item_unit_ext", "request_person", "request_person_ext", "request_unit", "request_unit_ext"};
//        Arrays.stream(tablenames).forEach(GenEntity::new);

        new GenEntity("jhrw_unit");
    }

}





